<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
<!-- emb-linux.qdoc -->
  <title>Qt for Embedded Linux | Qt 5.14</title>
  <link rel="stylesheet" type="text/css" href="style/offline-simple.css" />
  <script type="text/javascript">
    document.getElementsByTagName("link").item(0).setAttribute("href", "style/offline.css");
    // loading style sheet breaks anchors that were jumped to before
    // so force jumping to anchor again
    setTimeout(function() {
        var anchor = location.hash;
        // need to jump to different anchor first (e.g. none)
        location.hash = "#";
        setTimeout(function() {
            location.hash = anchor;
        }, 0);
    }, 0);
  </script>
</head>
<body>
<div class="header" id="qtdocheader">
  <div class="main">
    <div class="main-rounded">
      <div class="navigationbar">
        <table><tr>
<td ><a href="index.html">Qt 5.14</a></td><td >Qt for Embedded Linux</td></tr></table><table class="buildversion"><tr>
<td id="buildversion" width="100%" align="right">Qt 5.14.2 Reference Documentation</td>
        </tr></table>
      </div>
    </div>
<div class="content">
<div class="line">
<div class="content mainContent">
<div class="sidebar">
<div class="toc">
<h3><a name="toc">Contents</a></h3>
<ul>
<li class="level1"><a href="#platform-plugins-for-embedded-linux-devices">Platform Plugins for Embedded Linux Devices</a></li>
<li class="level2"><a href="#eglfs">EGLFS</a></li>
<li class="level2"><a href="#linuxfb">LinuxFB</a></li>
<li class="level1"><a href="#display-output">Display Output</a></li>
<li class="level2"><a href="#eglfs-with-the-eglfs-kms-backend">EGLFS with the eglfs_kms Backend</a></li>
<li class="level2"><a href="#advanced-eglfs-kms-features">Advanced eglfs_kms Features</a></li>
<li class="level2"><a href="#eglfs-with-eglfs-kms-egldevice-backend">eglfs with eglfs_kms_egldevice backend</a></li>
<li class="level2"><a href="#touch-input-in-systems-with-multiple-screens-on-kms-drm">Touch input in systems with multiple screens on KMS/DRM</a></li>
<li class="level2"><a href="#eglfs-with-other-backends">eglfs with other backends</a></li>
<li class="level2"><a href="#video-memory">Video Memory</a></li>
<li class="level2"><a href="#linuxfb">linuxfb</a></li>
<li class="level1"><a href="#unix-signal-handlers">Unix Signal Handlers</a></li>
<li class="level1"><a href="#fonts">Fonts</a></li>
<li class="level1"><a href="#platform-plugins-for-windowing-systems-on-embedded-linux-devices">Platform Plugins for Windowing Systems on Embedded Linux Devices</a></li>
<li class="level2"><a href="#xcb">XCB</a></li>
<li class="level2"><a href="#wayland">Wayland</a></li>
<li class="level1"><a href="#related-topics">Related Topics</a></li>
</ul>
</div>
<div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">Qt for Embedded Linux</h1>
<span class="subtitle"></span>
<!-- $$$embedded-linux.html-description -->
<div class="descr"> <a name="details"></a>
<p>On Embedded Linux systems, there are multiple platform plugins that you can use: EGLFS, <a href="embedded-linux.html#linuxfb">LinuxFB</a>, DirectFB, or Wayland. However, the availability of these plugins depend on how Qt is configured.</p>
<p>EGLFS is the default plugin on many boards. If it's not suitable, use the <code>QT_QPA_PLATFORM</code> environment variable to request another plugin. Alternatively, for quick tests, use the <code>-platform</code> command-line argument with the same syntax.</p>
<p><b>Note: </b>As of Qt 5.0, Qt no longer has its own window system (QWS) implementation. For single-process use cases, the <a href="qpa.html">Qt Platform Abstraction</a> is a superior solution; multi-process use cases are supported through <a href="license-changes.html#qt-wayland-compositor">Wayland</a>.</p><a name="platform-plugins-for-embedded-linux-devices"></a>
<h2 id="platform-plugins-for-embedded-linux-devices">Platform Plugins for Embedded Linux Devices</h2>
<a name="embedded-eglfs"></a><a name="eglfs"></a>
<h3 id="eglfs">EGLFS</h3>
<p><a href="http://www.khronos.org/egl">EGL</a> is an interface between OpenGL and the native windowing system. Qt can use EGL for context and surface management, however the API contains no platform-specifics. Creating a <i>native window</i>, which won't necessarily be an actual window on the screen, must still be done by platform-specific means. This is why we need the board or GPU-specific adaptation code. Typically, these adaptations are provided as:</p>
<ul>
<li><i>EGLFS hooks</i> -- a single source file compiled into the platform plugin</li>
<li><i>EGL device integration</i> -- dynamically loaded plugins</li>
</ul>
<p>EGLFS is a platform plugin for running Qt5 applications on top of EGL and OpenGL ES 2.0, without an actual windowing system like X11 or Wayland. In addition to Qt Quick 2 and native OpenGL applications, EGLFS supports software-rendered windows, like <a href="../qtwidgets/qwidget.html">QWidget</a>, too. For <a href="../qtwidgets/qwidget.html">QWidget</a>, the widgets' contents are rendered using the CPU into images, which are then uploaded into textures and composited by the plugin.</p>
<p>EGLFS is the recommended plugin for modern Embedded Linux devices that include a GPU.</p>
<p>EGLFS forces the first top-level window - either a <a href="../qtwidgets/qwidget.html">QWidget</a> or a <a href="../qtquick/qquickview.html">QQuickView</a> - to become fullscreen. This window is also chosen to be the <i>root</i> widget window into which all other top-level widgets are composited. For example, dialogs, popup menus, or combo boxes. This behavior is necessary because with EGLFS there is always exactly one native window and one EGL window surface; these belong to the widget or window that is created first. This approach works well when there is a main window that exists for the application's lifetime and all other widgets are either non top-levels or are created afterwards, once the main window is shown.</p>
<p>There are further restrictions for OpenGL-based windows. EGLFS supports a single single fullscreen GL window (as of Qt 5.3), like OpenGL-based <a href="../qtgui/qwindow.html">QWindow</a>, a <a href="../qtquick/qquickview.html">QQuickView</a>, or a <a href="../qtwidgets/qopenglwidget.html">QOpenGLWidget</a>. Opening additional OpenGL windows or mixing such windows with <a href="../qtwidgets/qwidget.html">QWidget</a>-based content isn't supported; Qt terminates the application with an error message.</p>
<p>If necessary, <code>eglfs</code> can be configured using the following environment variables:</p>
<div class="table"><table class="generic" width="100%">
 <thead><tr class="qt-style"><th >Environment Variable</th><th >Description</th></tr></thead>
<tr valign="top" class="odd"><td ><code>QT_QPA_EGLFS_INTEGRATION</code></td><td >In addition to the compiled-in <i>hooks</i>, it is also possible to use dynamically loaded plugins to provide device or vendor-specific adaptation. This environment variable enforces a specific plugin. For example, setting it to <i>eglfs_kms</i> uses the KMS/DRM backend. This is only an option when no static or compiled-in hooks were specified in the device makespecs. In practice, the traditional compiled-in hooks are rarely used, almost all backends are now migrated to plugins. The device makespecs still contain a relevant <code>EGLFS_DEVICE_INTEGRATION</code> entry: the name of the preferred backend for that particular device. This is optional, but very useful to avoid the need to set this environment variable if there are more than one plugin present in the target system. In a desktop environment the KMS or X11 backends are prioritized, depending on the presence of the <code>DISPLAY</code> environment variable.<p><b>Note: </b>On some boards a special value of <code>none</code> is used instead of an actual plugin. This indicates that no special integration is necessary to use EGL with the framebuffer; no plugins must be loaded.</p></td></tr>
<tr valign="top" class="even"><td ><code>QT_QPA_EGLFS_PHYSICAL_WIDTH</code> and <code>QT_QPA_EGLFS_PHYSICAL_HEIGHT</code></td><td >Specifies the physical screen's width and height in millimeters. On platforms where the value can't be queried from the framebuffer device <i>/dev/fb0</i> or via other means, a default DPI of 100 is used. Use this variable to override any such defaults. Setting this variable is important because <a href="../qtwidgets/qwidget.html">QWidget</a>- or Qt Quick Controls-based applications rely on these values. Running these applications with the hard-coded settings may result in user interface elements with sizes that are unsuitable for the display in use.</td></tr>
<tr valign="top" class="odd"><td ><code>QT_QPA_EGLFS_ROTATION</code></td><td >Specifies the rotation applied to software-rendered content in <a href="../qtwidgets/qwidget.html">QWidget</a>-based applications. Supported values are 180, 90, and -90. This variable does not apply to OpenGL-based windows, including Qt Quick. Qt Quick applications can apply transformations in their QML scene instead. The standard <code>eglfs</code> mouse cursor always takes the value into account, with an appropriately positioned and rotated pointer image, regardless of the application type. However, special cursor implementations, such as the KMS/DRM backend's hardware cursor, may not support rotation.</td></tr>
<tr valign="top" class="even"><td ><code>QT_QPA_EGLFS_FORCEVSYNC</code></td><td >When set, <code>eglfs</code> requests <code>FBIO_WAITFORVSYNC</code> on the framebuffer device after each call to eglSwapBuffers(). This variable is only relevant for backends relying on the legacy Linux <code>fbdev</code> subsystem. Normally, with a default swap interval of 1, Qt assumes that calling eglSwapBuffers() takes care of vsync; if it doesn't (for example, due to driver bugs), try setting <code>QT_QPA_EGLFS_FORCEVSYNC</code> to a non-zero value.</td></tr>
<tr valign="top" class="odd"><td ><code>QT_QPA_EGLFS_FORCE888</code></td><td >When set, the red, green, and blue color channel sizes are ignored when <code>eglfs</code> creates a new context, window or offscreen surface. Instead, the plugin requests a configuration with 8 bits per channel. This can be helpful on devices where configurations with less than 32 or 24 bits per pixel (for example, 5-6-5 or 4-4-4) are chosen by default despite knowing they are not ideal, for example, due to banding effects. Instead of changing application code, this variable provides a shortcut to force 24 or 32 bpp configurations.</td></tr>
</table></div>
<p>Additionally, the following less commonly used variables are available:</p>
<div class="table"><table class="generic" width="100%">
 <thead><tr class="qt-style"><th >Environment Variable</th><th >Description</th></tr></thead>
<tr valign="top" class="odd"><td ><code>QT_QPA_EGLFS_FB</code></td><td >Overrides the framebuffer device. The default is <code>/dev/fb0</code>. On most embedded platforms this variable isn't very relevant because the framebuffer is used only to query settings like the display dimensions. However, on certain devices, this variable provides the ability to specify which display to use in multiple display setups, similar to the <code>fb</code> parameter in <a href="embedded-linux.html#linuxfb">LinuxFB</a>.</td></tr>
<tr valign="top" class="even"><td ><code>QT_QPA_EGLFS_WIDTH</code> and <code>QT_QPA_EGLFS_HEIGHT</code></td><td >Contains the screen's width and height in pixels. While <code>eglfs</code> tries to determine the dimensions from the framebuffer device <i>/dev/fb0</i>, this doesn't always work. It may be necessary to manually specify the sizes.</td></tr>
<tr valign="top" class="odd"><td ><code>QT_QPA_EGLFS_DEPTH</code></td><td >Overrides the color depth for the screen. On platforms where the framebuffer device <i>/dev/fb0</i> is not available or the query is not successful, a default of <code>32</code> is used. Use this variable to override any such defaults.<p><b>Note: </b>This variable only affects the color depth value reported by <a href="../qtgui/qscreen.html">QScreen</a>. It has no connection to EGL configurations and the color depth used for OpenGL rendering.</p></td></tr>
<tr valign="top" class="even"><td ><code>QT_QPA_EGLFS_SWAPINTERVAL</code></td><td >By default, a swap interval of <code>1</code> is requested. This variable enables synchronizing to the display's vertical refresh. Use this variable to override the swap interval's value. For instance, passing 0 disables blocking on swap, resulting in running as fast as possible without any synchronization.</td></tr>
<tr valign="top" class="odd"><td ><code>QT_QPA_EGLFS_DEBUG</code></td><td >When set, some debugging information is printed on the debug output. For example, the input <a href="../qtgui/qsurfaceformat.html">QSurfaceFormat</a> and the properties of the chosen EGL configuration are printed while creating a new context. When used together with Qt Quick's <code>QSG_INFO</code> variable, you can get useful information for troubleshooting issues related to the EGL configuration.</td></tr>
</table></div>
<p>In addition to <code>QT_QPA_EGLFS_DEBUG</code>, <code>eglfs</code> also supports Qt's modern categorized logging system. The following logging categories are available:</p>
<ul>
<li><code>qt.qpa.egldeviceintegration</code> – Enables logging for dynamically loaded backends. Use this category to check what backend is in use.</li>
<li><code>qt.qpa.input</code> – Enables debug output both from the <code>evdev</code> and <code>libinput</code> input handlers. Use this category to check if a given input device was recognized and opened.</li>
<li><code>qt.qpa.eglfs.kms</code> – Enables verbose logging in the KMS/DRM backend.</li>
</ul>
<p>After running <code>configure</code>, make sure to inspect its output. This is the easiest, quickest way to identify whether you have the necessary EGLFS backend, libudev, or libinput enabled. In short, if there's an undesired &quot;no&quot; in your <code>configure</code> output, run:</p>
<pre class="cpp">

  <span class="operator">.</span><span class="operator">/</span>configure <span class="operator">-</span>v

</pre>
<p>to turn on the verbose output, so that you can see the compiler and linker invocations for each configure test.</p>
<p><b>Note: </b>If you encounter errors about missing headers, libraries, or seemingly cryptic linker failures, often, they are a sign of an incomplete or broken sysroot and isn't related to Qt.</p><p>As an example, when targeting the Raspberry Pi with the Broadcom proprietary graphics drivers, the output should contain something like the following:</p>
<pre class="cpp plain">

  QPA backends:
  EGLFS ..&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e; yes
  EGLFS details:
    EGLFS i.Mx6 ..&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e; no
    EGLFS i.Mx6 Wayland ..&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e; no
    EGLFS EGLDevice ..&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e; no
    EGLFS GBM ..&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e; no
    EGLFS Mali ..&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e; no
    EGLFS Rasberry Pi ..&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e; yes
    EGL on X11 ..&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e;&#x2e; no

</pre>
<p>If this is not the case, it's not advisable to proceed further with the build since accelerated graphics won't be functional without the Raspberry Pi-specific backend, even if the rest of Qt compiles successfully.</p>
<a name="linuxfb"></a>
<h3 id="linuxfb">LinuxFB</h3>
<p>This plugin writes directly to the framebuffer via Linux's fbdev subsystem. Only software-rendered content is supported. Note that on some setups the display performance is expected to be limited.</p>
<p>However, since fbdev is being deprecated in the Linux kernel, the DRM dumb buffer support is also available, as of Qt 5.9&#x2e; To use it, set the <code>QT_QPA_FB_DRM</code> environment variable to a non-zero value. When set, provided that dumb buffers are supported by your system, legacy framebuffer devices like <code>/dev/fb0</code> won't be accessed. Instead, the rendering is set up via the DRM APIs, similar to the <code>eglfs_kms</code> backend in EGLFS. The output is double-buffered and page flipped, providing proper vsync for software-rendered content as well.</p>
<p><b>Note: </b>When dumb buffers are in use, none of the options described below are applicable since properties like physical and logical screen sizes are all queried automatically.</p><p>The <code>linuxfb</code> plugin allows you to specify additional settings via the <code>QT_QPA_PLATFORM</code> environment variable or <code>-platform</code> command-line option. For example, <code>QT_QPA_PLATFORM=linuxfb:fb=/dev/fb1</code> specifies that the framebuffer device <code>/dev/fb1</code> must be used instead of the default <code>fb0</code>. To specify multiple settings, separate the mwith a colon (:).</p>
<div class="table"><table class="generic">
 <thead><tr class="qt-style"><th >Settings</th><th >Description</th></tr></thead>
<tr valign="top" class="odd"><td ><code>fb=/dev/fbN</code></td><td >Specifies the framebuffer devices. On multiple display setups, this setting allows you to run the application on different displays. Currently, there's no way to use multiple framebuffers from one Qt application.</td></tr>
<tr valign="top" class="even"><td ><code>size=</code><i>&lt;width&gt;</i><code>x</code><i>&lt;height&gt;</i></td><td >Specifies the screen size in pixels. The plugin tries to query the display dimensions, both physical and logical, from the framebuffer device. However, this query may not always lead to proper results; it may be necessary to specify the values explicitly.</td></tr>
<tr valign="top" class="odd"><td ><code>mmsize=</code><i>&lt;width&gt;</i><code>x</code><i>&lt;height&gt;</i></td><td >Specifies the physical width and height in millimeters.</td></tr>
<tr valign="top" class="even"><td ><code>offset=</code><i>&lt;width&gt;</i><code>x</code><i>&lt;height&gt;</i></td><td >Specifies the top-left corner of the screen offset in pixels. The default position is at <code>(0, 0)</code>.</td></tr>
<tr valign="top" class="odd"><td ><code>nographicsmodeswitch</code></td><td >Specifies not to switch the virtual terminal to graphics mode (<code>KD_GRAPHICS</code>). Typically, <i>enabling</i> graphics mode disables the blinking cursor and screen blanking. However, when this parameter is set, those two features are also skipped.</td></tr>
<tr valign="top" class="even"><td ><code>tty=/dev/ttyN</code></td><td >Overrides the virtual console. Only used when <code>nographicsmodeswitch</code> isn't set.</td></tr>
</table></div>
<p>As of Qt 5.9, the behavior of EGLFS and <a href="embedded-linux.html#linuxfb">LinuxFB</a> have been synchronized, with regards to the window sizing policy: the first top-level window is forced to cover the entire screen, with both platform plugins. If this is not desired, set the <code>QT_QPA_FB_FORCE_FULLSCREEN</code> environment variable to <code>0</code> to restore the behavior from earlier Qt versions.</p>
<a name="display-output"></a>
<h2 id="display-output">Display Output</h2>
<p>When you have multiple displays connected, the level of support to target one or more of these displays from one single Qt application, varies between the platform plugins and often depends on the device and its graphics stack.</p>
<a name="eglfs-with-the-eglfs-kms-backend"></a>
<h3 id="eglfs-with-the-eglfs-kms-backend">EGLFS with the eglfs_kms Backend</h3>
<p>When the KMS/DRM backend is in use, EGLFS reports all available screens in <a href="../qtgui/qguiapplication.html#screens">QGuiApplication::screens</a>(). Applications can target different screens with different windows via <a href="../qtgui/qwindow.html#setScreen">QWindow::setScreen</a>().</p>
<p><b>Note: </b>The restriction of one single fullscreen window per screen still applies. Changing screens after making the <a href="../qtgui/qwindow.html">QWindow</a> visible isn't supported either. Therefore, it's essential that embedded applications make all the necessary <a href="../qtgui/qwindow.html#setScreen">QWindow::setScreen</a>() calls before calling <a href="../qtgui/qwindow.html#show">QWindow::show</a>().</p><p>When you start developing on a given embedded device, often it's necessary to verify the behavior of the device and drivers, and that the connected displays are working as they should. One easy way is to use the <b>hellowindow</b> example. Launching it with the <code>-platform eglfs --multiscreen --timeout</code> arguments shows a rotating Qt logo on each connected screen for a few seconds.</p>
<p>The KMS/DRM backend also supports custom configurations via a JSON file. To enable this, set the <code>QT_QPA_EGLFS_KMS_CONFIG</code> environment variable to the name of the file. You can also embed this file into the application via the Qt resource system.</p>
<p>Most of these configuration options apply to all KMS/DRM-based backends, regardless of the buffer management technology (GBM or EGLStreams).</p>
<p>Here's an example configuration:</p>
<pre class="cpp plain">

  {
    &quot;device&quot;: &quot;/dev/dri/card1&quot;,
    &quot;hwcursor&quot;: false,
    &quot;pbuffers&quot;: true,
    &quot;outputs&quot;: [
      {
        &quot;name&quot;: &quot;VGA1&quot;,
        &quot;mode&quot;: &quot;off&quot;
      },
      {
        &quot;name&quot;: &quot;HDMI1&quot;,
        &quot;mode&quot;: &quot;1024x768&quot;
      }
    ]
  }

</pre>
<p>Here we configure the specified device so that:</p>
<ul>
<li>It won't use the hardware cursor (falls back to rendering the mouse cursor via OpenGL; by default hardware cursors are enabled as they're more efficient).</li>
<li>It backs <a href="../qtgui/qoffscreensurface.html">QOffscreenSurface</a> with standard EGL pbuffer surfaces (by default this is disabled and a gbm surface is used instead).</li>
<li>Output on the VGA connector is disabled, while HDMI is active with a resolution of 1024x768.</li>
</ul>
<p>Additionally, such a configuration also disables looking for a device via <code>libudev</code>; instead the specified device is used.</p>
<p>When <code>mode</code> is not defined, the system's preferred mode is chosen. The accepted values for <code>mode</code> are: <code>off</code>, <code>current</code>, <code>preferred</code>, <code>skip</code>, width<code>x</code>height, width<code>x</code>height<code>@</code>vrefresh, or a modeline string.</p>
<p>Specifying <code>current</code> chooses a mode with a resolution that matches the current one. Because modesetting is done only when the desired mode is actually different from the active one (unless forced via the <code>QT_QPA_EGLFS_ALWAYS_SET_MODE</code> environment variable), this value is useful to preserve the current mode and any content in the planes not touched by Qt.</p>
<p><code>skip</code> causes the connector for the output to be ignored, as if it were disconnected. <code>off</code> is similar, but it changes the mode and turns off the display.</p>
<p>By default, all screens reported by the DRM layer are treated as one big virtual desktop. The mouse cursor implementation takes this into account and moves across the screens as expected. Although not recommended, you can disable the virtual desktop by setting <code>separateScreens</code> to <code>false</code> in the configuration.</p>
<p>By default, the virtual desktop is formed left to right, based on the order of connectors as reported by the system. To change this, set <code>virtualIndex</code> to a value starting from 0.</p>
<p>For example, the following configuration uses the preferred resolution but ensures that the left side in the virtual desktop is the screen connected to the HDMI port; while the right side is the screen connected to the DisplayPort:</p>
<pre class="cpp plain">

  {
    &quot;device&quot;: &quot;drm-nvdc&quot;,
    &quot;outputs&quot;: [
      {
        &quot;name&quot;: &quot;HDMI1&quot;,
        &quot;virtualIndex&quot;: 0
      },
      {
        &quot;name&quot;: &quot;DP1&quot;,
        &quot;virtualIndex&quot;: 1
      }
    ]
  }

</pre>
<p>The order of elements in the array is not relevant. Outputs with unspecified virtual indices are placed after the others, with the original order in the DRM connector list preserved.</p>
<p>To create a vertical desktop space (that is, to stack top to bottom instead of left to right), add a <code>virtualDesktopLayout</code> property after <code>device</code> with the value of <code>vertical</code>.</p>
<p><b>Warning:</b> It's recommended that all screens in the virtual desktop use the same resolution, otherwise elements like the mouse cursor may behave in unexpected ways when entering areas that only exist on one given screen.</p>
<p>When <code>virtualIndex</code> is not sufficient, the <code>virtualPos</code> property can be used to explicitly specify the top-left position of the screen in question. Taking the previous example and assuming a resolution of 1080p for HDMI1, the following code snippet places a second HDMI-based screen below the first one:</p>
<pre class="cpp plain">

  {
     ..&#x2e;
    &quot;outputs&quot;: [
      ..&#x2e;
      {
        &quot;name&quot;: &quot;HDMI2&quot;,
        &quot;virtualPos&quot;: &quot;0, 1080&quot;
      }
    ]
  }

</pre>
<p><b>Note: </b>Avoid such configurations when mouse support is desired. The mouse cursor's behavior may be unexpected with non-linear layouts. Touch should present no issues however.</p><p>In some cases the automatic querying of the physical screen size via DRM may fail. Normally the <code>QT_QPA_EGLFS_PHYSICAL_WIDTH</code> and <code>QT_QPA_EGLFS_PHYSICAL_HEIGHT</code> environment variable would be used to provide the missing values, however this is not suitable anymore when multiple screens are present. Instead, use the <code>physicalWidth</code> and <code>physicalHeight</code> properties in the <code>outputs</code> list to specify the sizes in millimeters.</p>
<p><b>Note: </b>Different physical sizes and thus differing logical DPIs are discouraged because it may lead to unexpected issues due to some graphics stack components not knowing about multiple screens and relying solely on the first screen's values.</p><p>Each active output from the <code>outputs</code> array corresponds to one <a href="../qtgui/qscreen.html">QScreen</a> instance reported from <a href="../qtgui/qguiapplication.html#screens">QGuiApplication::screens</a>(). By default, the primary screen that <a href="../qtgui/qguiapplication.html#primaryScreen-prop">QGuiApplication::primaryScreen</a>() reports is the screen that is registered first. If you're not using <code>virtualIndex</code>, this means the decision is based on the DRM connector order. To override this, set the <code>primary</code> property to <code>true</code> on the desired entry in the <code>outputs</code> list.</p>
<p>For example, to ensure the screen corresponding to the VGA output is the primary even when the system happens to report the HDMI one first, do the following:</p>
<pre class="cpp plain">

  {
    &quot;device&quot;: &quot;/dev/dri/card0&quot;,
    &quot;outputs&quot;: [
        { &quot;name&quot;: &quot;HDMI1&quot; },
        { &quot;name&quot;: &quot;VGA1&quot;, &quot;mode&quot;: &quot;1280x720&quot;, &quot;primary&quot;: true },
        { &quot;name&quot;: &quot;LVDS1&quot;, &quot;mode&quot;: &quot;off&quot; }
    ]
  }

</pre>
<p>For troubleshooting it might be useful to enable debug logs from the KMS/DRM backend. To do this, enable the <code>qt.qpa.eglfs.kms</code> categorized logging rule.</p>
<p><b>Note: </b>In an embedded environment, virtual desktops are more limited compared to a full windowing system. Windows overlapping multiple screens, non-fullscreen windows, and moving windows between screens, should be avoided and may not function as expected.</p><p>The most common and best supported use case for a multi-screen setup is to open a dedicated <a href="../qtquick/qquickwindow.html">QQuickWindow</a> or <a href="../qtquick/qquickview.html">QQuickView</a> for each screen. With the default <code>threaded</code> render loop of the Qt Quick scenegraph, each of these windows will get its own dedicated render thread. This is good because the threads can be throttled independently based on vsync, and will not interfere with each other. With the <code>basic</code> loop this can get problematic, causing animations to degrade.</p>
<p>For example, discovering all connected screens and creating a <a href="../qtquick/qquickview.html">QQuickView</a> for each of them can be done like this:</p>
<pre class="cpp plain">

  int main(int argc, char **argv)
  {
      QGuiApplication app(argc, argv);

      QVector&lt;QQuickView *&gt; views;
      for (QScreen *screen : app.screens()) {
          QQuickView *view = new QQuickView;
          view-&gt;setScreen(screen);
          view-&gt;setResizeMode(QQuickView::SizeRootObjectToView);
          view-&gt;setSource(QUrl(&quot;qrc:/main.qml&quot;));
          QObject::connect(view-&gt;engine(), &amp;QQmlEngine::quit, qGuiApp, &amp;QCoreApplication::quit);
          views.append(view);
          view-&gt;showFullScreen();
      }

      int result = app.exec();

      qDeleteAll(views);
      return result;
  }

</pre>
<a name="advanced-eglfs-kms-features"></a>
<h3 id="advanced-eglfs-kms-features">Advanced eglfs_kms Features</h3>
<p>As of Qt 5.11, screen cloning (mirroring) is supported. This is enabled via the <code>clones</code> property:</p>
<pre class="cpp plain">

  {
    &quot;device&quot;: &quot;/dev/dri/card0&quot;,
    &quot;outputs&quot;: [
        { &quot;name&quot;: &quot;HDMI1&quot;, &quot;mode&quot;: &quot;1920x1080&quot; },
        { &quot;name&quot;: &quot;DP1&quot;, &quot;mode&quot;: &quot;1920x1080&quot;, &quot;clones&quot;: &quot;HDMI1&quot; }
   ]
  }

</pre>
<p>In this case, the content on the display connected via DisplayPort will be the same as on the HDMI one. This is ensured by scanning out the same buffer on both.</p>
<p>However, this feature can only work if the resolutions are the same, there are no incompatibilities when it comes to accepted buffer formats, and the application doesn't have any output on the <a href="../qtgui/qscreen.html">QScreen</a> associated with a clone destination. In practice, the latter means that no <a href="../qtgui/qwindow.html">QWindow</a> associated with the <a href="../qtgui/qscreen.html">QScreen</a> in question - DP1 in the example - must ever perform a <a href="../qtgui/qopenglcontext.html#swapBuffers">QOpenGLContext::swapBuffers</a>() operation. It's up to the configuration and the application to ensure these.</p>
<p>As of Qt 5.11, headless mode via DRM render nodes is supported. This allows performing GPU compute (OpenGL compute shaders, OpenCL) or offscreen OpenGL rendering without needing DRM master privileges. In this mode, applications can function even when there is already another process outputting to the screen.</p>
<p>Just switching <code>device</code> from <code>/dev/dri/card0</code> to <code>/dev/dri/renderD128</code> is futile on its own since there are a number of operations that cannot be performed in headless mode. Therefore, this must be combined with a <code>headless</code> property, for example:</p>
<pre class="cpp plain">

  {
      &quot;device&quot;: &quot;/dev/dri/renderD128&quot;,
      &quot;headless&quot;: &quot;1024x768&quot;
  }

</pre>
<p>Keep in mind that windows are still sized to match the - now virtual - screen size, hence the need for specifying a size in the <code>headless</code> property. There is also a lack of vsync-based throttling.</p>
<p>Once enabled, applications have two typical choices to perform offscreen rendering in headless mode:</p>
<p>Use an ordinary window, such as a <a href="../qtgui/qopenglwindow.html">QOpenGLWindow</a> subclass, targeting the window's default framebuffer, meaning a <code>gbm_surface</code> in practice:</p>
<pre class="cpp plain">

  MyOpenGLWindow w;
  w.show(); // will not actually show up on screen
  w.grabFramebuffer().save(&quot;output.png&quot;);

</pre>
<p>Or the typical offscreen approach with an extra FBO:</p>
<pre class="cpp plain">

  QOffscreenSurface s;
  s.setFormat(ctx.format());
  s.create();
  ctx.makeCurrent(&amp;s);
  QOpenGLFramebufferObject fbo(1024, 768);
  fbo.bind();
  ctx.functions()-&gt;glClearColor(1, 0, 0, 1);
  ctx.functions()-&gt;glClear(GL_COLOR_BUFFER_BIT);
  fbo.toImage().save(&quot;output.png&quot;);
  ctx.doneCurrent();

</pre>
<p>KMS/DRM can be used with two different DRM APIs which are <i>legacy</i> and <i>atomic</i>. The main benefit of DRM atomic API is to allow several DRM plane updates within the same renderloop, whereas legacy API would require one plane update per vsync.</p>
<p>Atomic API is useful when you application needs to blend content into overlays keeping all the updates within the same vsync. Still not all devices support this API and it could be unavailable on some older devices. KMS backend will by default use the legacy API, but you can enable the DRM atomic API with <code>QT_QPA_EGLFS_KMS_ATOMIC</code> environment variable set to 1.</p>
<p>Using a smaller framebuffer than screen resolution can also be useful. This is possible with DRM atomic using the <code>size</code> parameter in the JSON file. The example below uses a 1280x720 framebuffer on a 3840x2160 videomode :</p>
<pre class="cpp plain">

  {
    &quot;device&quot;: &quot;/dev/dri/card0&quot;,
    &quot;outputs&quot;: [
      { &quot;name&quot;: &quot;HDMI1&quot;, &quot;mode&quot;: &quot;3840x2160&quot;, &quot;size&quot;: &quot;1280x720&quot;, &quot;format&quot;: &quot;argb8888&quot; }
    ]
  }

</pre>
<a name="eglfs-with-eglfs-kms-egldevice-backend"></a>
<h3 id="eglfs-with-eglfs-kms-egldevice-backend">eglfs with eglfs_kms_egldevice backend</h3>
<p>This backend, typically used on Tegra devices, is similar to the KMS/DRM backend mentioned above, except that it relies on the EGLDevice and EGLStream extensions instead of GBM.</p>
<p>For technical details about this approach, check out <a href="https://wiki.qt.io/Qt_for_Embedded_Linux/XDC2014RitgerEGLNonMesa">this presentation</a>.</p>
<p>As of Qt 5.7 this backend shares many of its internal implementation with the GBM-based backend. This means that multiple screens and the advanced configuration via <code>QT_QPA_EGLFS_KMS_CONFIG</code> are supported. Some settings, such as <code>hwcursor</code> and <code>pbuffers</code> are not applicable however.</p>
<p>By default the backend will automatically choose the correct EGL layer for the default plane of each output. When necessary, this can be overridden by setting the <code>QT_QPA_EGLFS_LAYER_INDEX</code> environment variable to the index of the desired layer. This approach does not currently support multiple outputs, so its usage should be limited to systems with a single screen. To see which layers are available, and to debug potential startup issues, enable the logging category <code>qt.qpa.eglfs.kms</code>.</p>
<p>In some cases it may be necessary to perform a video mode set on application startup even when the screen reports that the desired resolution is already set. This is normally optimized away, but if the screen stays powered down, try setting the environment variable <code>QT_QPA_EGLFS_ALWAYS_SET_MODE</code> to a non-zero value and relaunch the application.</p>
<p>To configure the behavior of the EGLStream object used by the backend, use the <code>QT_QPA_EGLFS_STREAM_FIFO_LENGTH</code> environment variable. This assumes that <code>KHR_stream_fifo</code> is supported by the target system. By default the stream operates in mailbox mode. To switch to FIFO mode, set a value of 1 or greater. The value specifies the maximum number of frames the stream can hold.</p>
<p>On some systems it may become necessary to target a specific overlay plane through a pre-defined connector. Just forcing a layer index via <code>QT_QPA_EGLFS_LAYER_INDEX</code> does not perform plane configuration and is therefore not suitable in itself. Instead, in such special scenarios use the <code>QT_QPA_EGLFS_KMS_CONNECTOR_INDEX</code> and <code>QT_QPA_EGLFS_KMS_PLANE_INDEX</code> environment variables. When these are set, only the specified connector and plane will be in use, all other outputs will get ignored. The backend will take care of picking the EGL layer that corresponds to the desired plane, and the configuring of the plane.</p>
<a name="touch-input-in-systems-with-multiple-screens-on-kms-drm"></a>
<h3 id="touch-input-in-systems-with-multiple-screens-on-kms-drm">Touch input in systems with multiple screens on KMS/DRM</h3>
<p>Touchscreens require additional considerations in multi-display systems because touch events have to be routed to the correct virtual screen, and this requires a correct mapping between touchscreens and display outputs.</p>
<p>The mapping is done via the JSON configuration file specified in <code>QT_QPA_EGLFS_KMS_CONFIG</code> and described in the previous sections. When a <code>touchDevice</code> property is present in an element of the <code>outputs</code> array, the value is treated as a device node and the touch device is associated with the display output in question.</p>
<p>For example, assuming our touchscreen has a device node of /dev/input/event5 and is a touchscreen integrated into the monitor connected via HDMI as the secondary screen, the following configuration ensures correct touch (and synthesized mouse) event translation:</p>
<pre class="cpp plain">

   {
      &quot;device&quot;: &quot;drm-nvdc&quot;,
      &quot;outputs&quot;: [
        {
          &quot;name&quot;: &quot;HDMI1&quot;,
          &quot;touchDevice&quot;: &quot;/dev/input/event5&quot;,
          &quot;virtualIndex&quot;: 1
        },
        {
          &quot;name&quot;: &quot;DP1&quot;,
          &quot;virtualIndex&quot;: 0
        }
      ]
  }

</pre>
<p><b>Note: </b>When in doubt, enable logging from both the graphics and input subsystems by setting the environment variable <code>QT_LOGGING_RULES=qt.qpa.*=true</code> before launching the application. This will help identifying the correct input device nodes and may uncover output configuration issues that can be difficult to debug otherwise.</p><p><b>Note: </b>As of Qt 5.8, the above is only supported for the evdevtouch input backend. Other variants, such as the libinput-based one, will continue to route events to the primary screen. To force the usage of evdevtouch on systems where multiple input backends are available, set the environment variable <code>QT_QPA_EGLFS_NO_LIBINPUT</code> to <code>1</code>.</p><a name="eglfs-with-other-backends"></a>
<h3 id="eglfs-with-other-backends">eglfs with other backends</h3>
<p>Other backends, that are typically based on targeting the framebuffer or a composition API directly via the vendor's EGL implementation, usually provide limited or no support for multiple displays. On i.MX6-based boards with Vivante GPUs the <code>QT_QPA_EGLFS_FB</code> environment variable can be used to specify the framebuffer to target, similarly to linuxfb. On the Raspberry Pi the <code>QT_QPA_EGLFS_DISPMANX_ID</code> environment variable can be used to specify the screen to output to. The value corresponds to one of the <code>DISPMANX_ID_</code> constants, refer to the Dispmanx documentation. Note that these approaches, unlike KMS/DRM, will not typically allow to output to multiple screens from the same application. Alternatively, driver-specific environment variables or kernel parameters may also be available as well to control the used framebuffer. Refer to the embedded board's documentation.</p>
<a name="video-memory"></a>
<h3 id="video-memory">Video Memory</h3>
<p>Systems with a fixed amount of dedicated video memory may need extra care before running Qt application based on Qt Quick or classes like <a href="../qtwidgets/qopenglwidget.html">QOpenGLWidget</a>. The default setting may be insufficient for such applications, especially when they are displayed on a high resolution (for example, full HD) screen. In this case, they may start failing in unexpected ways. It is recommended to ensure that there is at least 128 MB of GPU memory available. For systems that do not have a fixed amount of memory reserved for the GPU this is not an issue.</p>
<a name="linuxfb"></a>
<h3 id="linuxfb">linuxfb</h3>
<p>Use the <code>fb</code> plugin parameter to specify the framebuffer device to use.</p>
<a name="unix-signal-handlers"></a>
<h2 id="unix-signal-handlers">Unix Signal Handlers</h2>
<p>The console-oriented platform plugins like eglfs and linuxfb install signal handlers by default to capture interrupt (<code>SIGINT</code>), suspend and continue (<code>SIGTSTP</code>, <code>SIGCONT</code>) and termination (<code>SIGTERM</code>). This way the keyboard, terminal cursor, and possibly other graphics state can be restored when the application terminates or gets suspended due to <code>kill</code>, or <code>Ctrl+C</code> or <code>Ctrl+Z</code>. (although terminating or suspending via the keyboard is only possible when <code>QT_QPA_ENABLE_TERMINAL_KEYBOARD</code> is set, as outlined above in the Input section). However, in some cases capturing <code>SIGINT</code> can be undesirable as it may conflict with remote debugging for instance. Therefore, the environment variable <code>QT_QPA_NO_SIGNAL_HANDLER</code> is provided to opt out from all built-in signal handling.</p>
<a name="fonts"></a>
<h2 id="fonts">Fonts</h2>
<p>Qt normally uses <code>fontconfig</code> to provide access to system fonts. If <code>fontconfig</code> is not available, Qt will fall back to using <code>QBasicFontDatabase</code>. In this case, Qt applications will look for fonts in Qt's <code>lib/fonts</code> directory. Qt will automatically detect pre-rendered fonts and TrueType fonts. This directory can be overridden by setting the <code>QT_QPA_FONTDIR</code> environment variable.</p>
<p>For more information on the supported formats, see <a href="qt-embedded-fonts.html">Qt for Embedded Linux Fonts</a>.</p>
<p><b>Note: </b>Qt no longer ships any fonts in the <code>lib/fonts</code> directory. This means that it is up to the platform (the system image) to provide the necessary fonts.</p><a name="platform-plugins-for-windowing-systems-on-embedded-linux-devices"></a>
<h2 id="platform-plugins-for-windowing-systems-on-embedded-linux-devices">Platform Plugins for Windowing Systems on Embedded Linux Devices</h2>
<a name="xcb"></a>
<h3 id="xcb">XCB</h3>
<p>This is the X11 plugin used on regular desktop Linux platforms. In some embedded environments, that provide X and the necessary development files for <a href="http://xcb.freedesktop.org">xcb</a>, this plugin functions just like it does on a regular PC desktop.</p>
<p><b>Note: </b>On some devices there is no EGL and OpenGL support available under X because the EGL implementation is not compatible with Xlib. In this case the XCB plugin is built without EGL support, meaning that Qt Quick 2 or other OpenGL-based applications does not work with this platform plugin. It can still be used however to run software-rendered applications (based on <a href="../qtwidgets/qwidget.html">QWidget</a> for example).</p><p>As a general rule, the usage of XCB on embedded devices is not advisable. Plugins like eglfs are likely to provide better performance, and hardware acceleration.</p>
<a name="wayland"></a>
<h3 id="wayland">Wayland</h3>
<p><a href="http://wayland.freedesktop.org/">Wayland</a> is a light-weight windowing system; or more precisely, it is a protocol for clients to talk to a display server.</p>
<p>Qt Wayland provides a <code>wayland</code> platform plugin that allows Qt applications to connect to a Wayland compositor.</p>
<p>For more details, see <a href="wayland-and-qt.html">Wayland and Qt</a>.</p>
<a name="related-topics"></a>
<h2 id="related-topics">Related Topics</h2>
<ul>
<li><a href="http://doc.qt.io/QtForDeviceCreation">Qt for Device Creation</a></li>
<li><a href="configure-linux-device.html">Configure an Embedded Linux Device</a></li>
<li><a href="inputs-linux-device.html">Inputs on an Embedded Linux Device</a></li>
<li><a href="http://doc.qt.io/emulator/index.html">Emulator</a></li>
<li><a href="../qtvirtualkeyboard/qtvirtualkeyboard-index.html">Qt Virtual Keyboard</a></li>
<li><a href="webgl.html">Qt Quick WebGL</a></li>
</ul>
</div>
<!-- @@@embedded-linux.html -->
        </div>
       </div>
   </div>
   </div>
</div>
<div class="footer">
   <p>
   <acronym title="Copyright">&copy;</acronym> 2020 The Qt Company Ltd.
   Documentation contributions included herein are the copyrights of
   their respective owners.<br/>    The documentation provided herein is licensed under the terms of the    <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation    License version 1.3</a> as published by the Free Software Foundation.<br/>    Qt and respective logos are trademarks of The Qt Company Ltd.     in Finland and/or other countries worldwide. All other trademarks are property
   of their respective owners. </p>
</div>
</body>
</html>
